home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / gnu / oleo_src.lha / src / msd_dir.c < prev    next >
C/C++ Source or Header  |  1992-07-27  |  4KB  |  220 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  */
  8.  
  9. #include    <sys/types.h>
  10. #include    <sys/stat.h>
  11. /* #include    <malloc.h> */
  12. #include    <dos.h>
  13. #include    <string.h>
  14. #include    <sys/dir.h>
  15.  
  16. #ifndef    NULL
  17. # define    NULL    0
  18. #endif    /* NULL */
  19.  
  20. #ifndef    MAXPATHLEN
  21. # define    MAXPATHLEN    64
  22. #endif    /* MAXPATHLEN */
  23.  
  24. /* attribute stuff */
  25. #define    A_RONLY        0x01
  26. #define    A_HIDDEN    0x02
  27. #define    A_SYSTEM    0x04
  28. #define    A_LABEL        0x08
  29. #define    A_DIR        0x10
  30. #define    A_ARCHIVE    0x20
  31.  
  32. /* dos call values */
  33. #define    DOSI_FINDF    0x4e
  34. #define    DOSI_FINDN    0x4f
  35. #define    DOSI_SDTA    0x1a
  36.  
  37. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  38. /* #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM) */
  39. #define ATTRIBUTES    (A_RONLY | A_SYSTEM | A_DIR)
  40.  
  41. /* what find first/next calls look use */
  42. typedef struct {
  43.     char        d_buf[21];
  44.     char        d_attribute;
  45.     unsigned short    d_time;
  46.     unsigned short    d_date;
  47.     long        d_size;
  48.     char        d_name[13];
  49. } Dta_buf;
  50.  
  51. extern void *malloc();
  52. extern void free();
  53.  
  54. static    char    *getdirent();
  55. static    void    setdta();
  56. static    void    free_dircontents();
  57.  
  58. static    Dta_buf        dtabuf;
  59. static    Dta_buf        *dtapnt = &dtabuf;
  60. static    union REGS    reg, nreg;
  61.  
  62. #if    defined(M_I86LM)
  63. static    struct SREGS    sreg;
  64. #endif
  65.  
  66. DIR    *
  67. opendir(name)
  68.     char    *name;
  69. {
  70.     struct    stat        statb;
  71.     DIR            *dirp;
  72.     char            c;
  73.     char            *s;
  74.     struct _dircontents    *dp;
  75.     char            nbuf[MAXPATHLEN + 1];
  76.     
  77.     if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  78.         return (DIR *) NULL;
  79.     if (Newisnull(dirp, DIR))
  80.         return (DIR *) NULL;
  81.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  82.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  83.     else
  84.         (void) strcat(strcpy(nbuf, name), "*.*");
  85.     dirp->dd_loc = 0;
  86.     setdta();
  87.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  88.     if ((s = getdirent(nbuf)) == (char *) NULL)
  89.         return dirp;
  90.     do {
  91.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  92.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  93.         {
  94.             if (dp)
  95.                 free((char *) dp);
  96.             free_dircontents(dirp->dd_contents);
  97.             return (DIR *) NULL;
  98.         }
  99.         if (dirp->dd_contents)
  100.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  101.         else
  102.             dirp->dd_contents = dirp->dd_cp = dp;
  103.         (void) strcpy(dp->_d_entry, s);
  104.         dp->_d_next = (struct _dircontents *) NULL;
  105.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  106.     dirp->dd_cp = dirp->dd_contents;
  107.  
  108.     return dirp;
  109. }
  110.  
  111. void
  112. closedir(dirp)
  113.     DIR    *dirp;
  114. {
  115.     free_dircontents(dirp->dd_contents);
  116.     free((char *) dirp);
  117. }
  118.  
  119. struct direct    *
  120. readdir(dirp)
  121.     DIR    *dirp;
  122. {
  123.     static    struct direct    dp;
  124.     
  125.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  126.         return (struct direct *) NULL;
  127.     dp.d_namlen = dp.d_reclen =
  128.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  129.     strlwr(dp.d_name);        /* JF */
  130.     dp.d_ino = 0;
  131.     dirp->dd_cp = dirp->dd_cp->_d_next;
  132.     dirp->dd_loc++;
  133.  
  134.     return &dp;
  135. }
  136.  
  137. void
  138. seekdir(dirp, off)
  139.     DIR    *dirp;
  140.     long    off;
  141. {
  142.     long            i = off;
  143.     struct _dircontents    *dp;
  144.  
  145.     if (off < 0)
  146.         return;
  147.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  148.         ;
  149.     dirp->dd_loc = off - (i + 1);
  150.     dirp->dd_cp = dp;
  151. }
  152.  
  153. long
  154. telldir(dirp)
  155.     DIR    *dirp;
  156. {
  157.     return dirp->dd_loc;
  158. }
  159.  
  160. static    void
  161. free_dircontents(dp)
  162.     struct    _dircontents    *dp;
  163. {
  164.     struct _dircontents    *odp;
  165.  
  166.     while (dp) {
  167.         if (dp->_d_entry)
  168.             free(dp->_d_entry);
  169.         dp = (odp = dp)->_d_next;
  170.         free((char *) odp);
  171.     }
  172. }
  173.  
  174. static    char    *
  175. getdirent(dir)
  176.     char    *dir;
  177. {
  178.     if (dir != (char *) NULL) {        /* get first entry */
  179.         reg.h.ah = DOSI_FINDF;
  180.         reg.h.cl = ATTRIBUTES;
  181. #if    defined(M_I86LM)
  182.         reg.x.dx = FP_OFF(dir);
  183.         sreg.ds = FP_SEG(dir);
  184. #else
  185.         reg.x.dx = (unsigned) dir;
  186. #endif
  187.     } else {                /* get next entry */
  188.         reg.h.ah = DOSI_FINDN;
  189. #if    defined(M_I86LM)
  190.         reg.x.dx = FP_OFF(dtapnt);
  191.         sreg.ds = FP_SEG(dtapnt);
  192. #else
  193.         reg.x.dx = (unsigned) dtapnt;
  194. #endif
  195.     }
  196. #if    defined(M_I86LM)
  197.     intdosx(®, &nreg, &sreg);
  198. #else
  199.     intdos(®, &nreg);
  200. #endif
  201.     if (nreg.x.cflag)
  202.         return (char *) NULL;
  203.  
  204.     return dtabuf.d_name;
  205. }
  206.  
  207. static    void
  208. setdta()
  209. {
  210.     reg.h.ah = DOSI_SDTA;
  211. #if    defined(M_I86LM)
  212.     reg.x.dx = FP_OFF(dtapnt);
  213.     sreg.ds = FP_SEG(dtapnt);
  214.     intdosx(®, &nreg, &sreg);
  215. #else
  216.     reg.x.dx = (int) dtapnt;
  217.     intdos(®, &nreg);
  218. #endif
  219. }
  220.